﻿using System;
using System.Linq.Expressions;
using Library.Distributed;

namespace Library.Linq.Expressions
{
    public class BarrierExpression : DistributedExpression
    {
        internal BarrierExpression() { }
        internal BarrierExpression(Expression timeout)
        {
            if (timeout != null)
            {
                if (timeout.Type != typeof(uint) && timeout.Type != typeof(TimeSpan)) throw new ArgumentException();
                this.timeout = timeout;
            }
        }

        public override Type Type
        {
            get
            {
                return typeof(bool);
            }
        }

        Expression timeout;

        public override Expression Reduce()
        {
            if (timeout != null)
            {
                var timeoutType = timeout.Type;
                if (timeoutType == typeof(uint))
                {
                    return Expression.Call(Context_Current, typeof(Context).GetMethod("Barrier", new Type[] { typeof(uint) }), timeout);
                }
                else
                {
                    return Expression.Call(Context_Current, typeof(Context).GetMethod("Barrier", new Type[] { typeof(TimeSpan) }), timeout);
                }
            }
            else
            {
                return Expression.Call(Context_Current, typeof(Context).GetMethod("Barrier", new Type[] { }));
            }
        }
    }
}
